// Store工具函数
import { StoreApi } from 'zustand'

// 订阅管理器
export class SubscriptionManager {
    private subscriptions: (() => void)[] = []

    // 添加订阅
    add(unsubscribe: () => void): void {
        this.subscriptions.push(unsubscribe)
    }

    // 清理所有订阅
    cleanup(): void {
        this.subscriptions.forEach(unsubscribe => {
            try {
                unsubscribe()
            } catch (error) {
                console.warn('Error during subscription cleanup:', error)
            }
        })
        this.subscriptions = []
    }

    // 获取订阅数量
    get count(): number {
        return this.subscriptions.length
    }
}

// 创建订阅管理器
export const createSubscriptionManager = (): SubscriptionManager => {
    return new SubscriptionManager()
}

// Store状态比较工具
export const createStateComparator = <T>(
    selector: (state: T) => unknown,
    compareFn?: (a: unknown, b: unknown) => boolean
) => {
    const defaultCompare = (a: unknown, b: unknown): boolean => {
        return Object.is(a, b)
    }

    const compare = compareFn || defaultCompare
    let previousValue: unknown

    return (state: T): boolean => {
        const currentValue = selector(state)
        const hasChanged = !compare(previousValue, currentValue)
        previousValue = currentValue
        return hasChanged
    }
}

// 深度比较函数
export const deepEqual = (a: unknown, b: unknown): boolean => {
    if (a === b) return true

    if (a == null || b == null) return a === b

    if (typeof a !== typeof b) return false

    if (typeof a !== 'object') return a === b

    if (Array.isArray(a) !== Array.isArray(b)) return false

    if (Array.isArray(a)) {
        const arrA = a as unknown[]
        const arrB = b as unknown[]

        if (arrA.length !== arrB.length) return false

        return arrA.every((item, index) => deepEqual(item, arrB[index]))
    }

    const objA = a as Record<string, unknown>
    const objB = b as Record<string, unknown>

    const keysA = Object.keys(objA)
    const keysB = Object.keys(objB)

    if (keysA.length !== keysB.length) return false

    return keysA.every(key =>
        keysB.includes(key) && deepEqual(objA[key], objB[key])
    )
}

// 浅比较函数
export const shallowEqual = (a: unknown, b: unknown): boolean => {
    if (a === b) return true

    if (a == null || b == null) return a === b

    if (typeof a !== 'object' || typeof b !== 'object') return a === b

    if (Array.isArray(a) !== Array.isArray(b)) return false

    if (Array.isArray(a)) {
        const arrA = a as unknown[]
        const arrB = b as unknown[]

        if (arrA.length !== arrB.length) return false

        return arrA.every((item, index) => item === arrB[index])
    }

    const objA = a as Record<string, unknown>
    const objB = b as Record<string, unknown>

    const keysA = Object.keys(objA)
    const keysB = Object.keys(objB)

    if (keysA.length !== keysB.length) return false

    return keysA.every(key =>
        keysB.includes(key) && objA[key] === objB[key]
    )
}

// 防抖订阅
export const createDebouncedSubscription = <T>(
    store: StoreApi<T>,
    selector: (state: T) => unknown,
    callback: (value: unknown, previousValue: unknown) => void,
    delay: number = 300
): (() => void) => {
    let timeoutId: NodeJS.Timeout | null = null
    let previousValue = selector(store.getState())

    return store.subscribe((state) => {
        const currentValue = selector(state)

        if (timeoutId) {
            clearTimeout(timeoutId)
        }

        timeoutId = setTimeout(() => {
            if (!Object.is(currentValue, previousValue)) {
                callback(currentValue, previousValue)
                previousValue = currentValue
            }
        }, delay)
    })
}

// 节流订阅
export const createThrottledSubscription = <T>(
    store: StoreApi<T>,
    selector: (state: T) => unknown,
    callback: (value: unknown, previousValue: unknown) => void,
    delay: number = 1000
): (() => void) => {
    let lastCallTime = 0
    let previousValue = selector(store.getState())

    return store.subscribe((state) => {
        const currentValue = selector(state)
        const now = Date.now()

        if (now - lastCallTime >= delay && !Object.is(currentValue, previousValue)) {
            callback(currentValue, previousValue)
            previousValue = currentValue
            lastCallTime = now
        }
    })
}

// 批量订阅
export const createBatchSubscription = <T>(
    store: StoreApi<T>,
    subscriptions: Array<{
        selector: (state: T) => unknown
        callback: (value: unknown, previousValue: unknown) => void
        compare?: (a: unknown, b: unknown) => boolean
    }>
): (() => void) => {
    const previousValues = subscriptions.map(sub => sub.selector(store.getState()))

    return store.subscribe((state) => {
        subscriptions.forEach((sub, index) => {
            const currentValue = sub.selector(state)
            const previousValue = previousValues[index]
            const compare = sub.compare || Object.is

            if (!compare(currentValue, previousValue)) {
                sub.callback(currentValue, previousValue)
                previousValues[index] = currentValue
            }
        })
    })
}

// Store性能监控
export class StorePerformanceMonitor {
    private metrics: Map<string, number[]> = new Map()
    private maxSamples: number = 100

    constructor(maxSamples: number = 100) {
        this.maxSamples = maxSamples
    }

    // 记录性能指标
    record(metricName: string, value: number): void {
        if (!this.metrics.has(metricName)) {
            this.metrics.set(metricName, [])
        }

        const samples = this.metrics.get(metricName)!
        samples.push(value)

        // 保持样本数量在限制内
        if (samples.length > this.maxSamples) {
            samples.shift()
        }
    }

    // 获取平均值
    getAverage(metricName: string): number {
        const samples = this.metrics.get(metricName)
        if (!samples || samples.length === 0) return 0

        return samples.reduce((sum, value) => sum + value, 0) / samples.length
    }

    // 获取最大值
    getMax(metricName: string): number {
        const samples = this.metrics.get(metricName)
        if (!samples || samples.length === 0) return 0

        return Math.max(...samples)
    }

    // 获取最小值
    getMin(metricName: string): number {
        const samples = this.metrics.get(metricName)
        if (!samples || samples.length === 0) return 0

        return Math.min(...samples)
    }

    // 获取第95百分位
    getP95(metricName: string): number {
        const samples = this.metrics.get(metricName)
        if (!samples || samples.length === 0) return 0

        const sorted = [...samples].sort((a, b) => a - b)
        const index = Math.floor(sorted.length * 0.95)
        return sorted[index] || 0
    }

    // 清除指标
    clear(metricName?: string): void {
        if (metricName) {
            this.metrics.delete(metricName)
        } else {
            this.metrics.clear()
        }
    }

    // 获取所有指标报告
    getReport(): Record<string, {
        average: number
        max: number
        min: number
        p95: number
        samples: number
    }> {
        const report: Record<string, {
            average: number
            max: number
            min: number
            p95: number
            samples: number
        }> = {}

        for (const [metricName] of this.metrics) {
            report[metricName] = {
                average: this.getAverage(metricName),
                max: this.getMax(metricName),
                min: this.getMin(metricName),
                p95: this.getP95(metricName),
                samples: this.metrics.get(metricName)?.length || 0
            }
        }

        return report
    }
}

// 创建性能监控装饰器
export const withPerformanceMonitoring = <T extends (...args: unknown[]) => unknown>(
    fn: T,
    metricName: string,
    monitor: StorePerformanceMonitor
): T => {
    return ((...args: Parameters<T>) => {
        const startTime = performance.now()

        try {
            const result = fn(...args)

            // 如果是Promise，监控异步执行时间
            if (result instanceof Promise) {
                return result.finally(() => {
                    const endTime = performance.now()
                    monitor.record(metricName, endTime - startTime)
                })
            }

            // 同步执行
            const endTime = performance.now()
            monitor.record(metricName, endTime - startTime)
            return result

        } catch (error) {
            const endTime = performance.now()
            monitor.record(`${metricName}_error`, endTime - startTime)
            throw error
        }
    }) as T
}

// Store状态快照工具
export class StoreSnapshot<T> {
    private snapshots: Map<string, T> = new Map()

    // 创建快照
    create(name: string, state: T): void {
        this.snapshots.set(name, JSON.parse(JSON.stringify(state)))
    }

    // 获取快照
    get(name: string): T | null {
        return this.snapshots.get(name) || null
    }

    // 比较快照
    compare(name1: string, name2: string): {
        equal: boolean
        differences: string[]
    } {
        const snapshot1 = this.get(name1)
        const snapshot2 = this.get(name2)

        if (!snapshot1 || !snapshot2) {
            return {
                equal: false,
                differences: ['One or both snapshots not found']
            }
        }

        const differences: string[] = []
        const equal = deepEqual(snapshot1, snapshot2)

        if (!equal) {
            // 这里可以实现更详细的差异检测
            differences.push('States are different')
        }

        return { equal, differences }
    }

    // 删除快照
    delete(name: string): boolean {
        return this.snapshots.delete(name)
    }

    // 清除所有快照
    clear(): void {
        this.snapshots.clear()
    }

    // 列出所有快照
    list(): string[] {
        return Array.from(this.snapshots.keys())
    }
}

// 创建Store调试工具
export const createStoreDebugger = <T>(
    store: StoreApi<T>,
    storeName: string
) => {
    const monitor = new StorePerformanceMonitor()
    const snapshot = new StoreSnapshot<T>()

    // 监控状态变化
    const unsubscribe = store.subscribe((state, previousState) => {
        if (process.env.NODE_ENV === 'development') {
            console.group(`🏪 ${storeName} State Change`)
            console.log('Previous:', previousState)
            console.log('Current:', state)
            console.groupEnd()
        }
    })

    return {
        monitor,
        snapshot,
        unsubscribe,

        // 创建当前状态快照
        takeSnapshot: (name?: string) => {
            const snapshotName = name || `snapshot_${Date.now()}`
            snapshot.create(snapshotName, store.getState())
            return snapshotName
        },

        // 获取性能报告
        getPerformanceReport: () => monitor.getReport(),

        // 清理
        cleanup: () => {
            unsubscribe()
            monitor.clear()
            snapshot.clear()
        }
    }
}

// 导出全局性能监控实例
export const globalPerformanceMonitor = new StorePerformanceMonitor(1000)

const storeUtils = {
    SubscriptionManager,
    createSubscriptionManager,
    createStateComparator,
    deepEqual,
    shallowEqual,
    createDebouncedSubscription,
    createThrottledSubscription,
    createBatchSubscription,
    StorePerformanceMonitor,
    withPerformanceMonitoring,
    StoreSnapshot,
    createStoreDebugger,
    globalPerformanceMonitor
}

export default storeUtils